/**
在 Redux 中，使用 Hooks（特别是  `useSelector`  和  `useDispatch` ）可以更方便地在函数组件中访问 Redux store 的状态和派发动作。
  1. 核心 Hooks
   1.1  `useSelector` 
  - 作用： `useSelector`  用于从 Redux store 中选择状态。它接受一个选择器函数，该函数接收整个 Redux store 的状态并返回所需的部分。
  - 使用方式：
  import { useSelector } from 'react-redux';

  const MyComponent = () => {
    // 从 Redux store 中选择状态
    const value = useSelector(state => state.someValue);

    return <div>{value}</div>;
  };
  - 特点：
    -  `useSelector`  会在所选择的状态发生变化时重新渲染组件。
    - 选择器函数可以是简单的属性访问，也可以是复杂的计算。

   1.2  `useDispatch` 
  - 作用： `useDispatch`  用于获取 Redux store 的  `dispatch`  函数，以便派发动作。
  - 使用方式：
  import { useDispatch } from 'react-redux';

  const MyComponent = () => {
    const dispatch = useDispatch();

    const handleClick = () => {
      dispatch({ type: 'INCREMENT' });
    };

    return <button onClick={handleClick}>Increment</button>;
  };
  - 特点：
    -  `useDispatch`  返回的  `dispatch`  函数可以用来派发任何动作。
    - 可以与 thunk 或其他中间件结合使用来处理异步操作。

  2. 使用 Hooks 的优点
  - 简化代码：使用 Hooks 可以减少样板代码，避免使用  `connect`  函数，使得组件更简洁。
  - 更好的可读性：Hooks 提供了更直观的 API，便于理解组件的状态和行为。
  - 更灵活的组合：可以在组件中自由使用多个 Hooks，灵活组合不同的状态和逻辑。

  3. 示例
  结合  `useSelector`  和  `useDispatch`  的完整示例：
  import React from 'react';
  import { useSelector, useDispatch } from 'react-redux';

  const Counter = () => {
    const count = useSelector(state => state.count);
    const dispatch = useDispatch();

    const increment = () => {
      dispatch({ type: 'INCREMENT' });
    };

    const decrement = () => {
      dispatch({ type: 'DECREMENT' });
    };

    return (
      <div>
        <h1>{count}</h1>
        <button onClick={increment}>Increment</button>
        <button onClick={decrement}>Decrement</button>
      </div>
    );
  };

  export default Counter;

  4. 总结
  在 Redux 中使用 Hooks（ `useSelector`  和  `useDispatch` ）提供了一种更简洁和直观的方式来访问和管理应用状态。它们使得函数组件能够轻松访问 Redux store 的状态和派发动作，提升了代码的可读性和可维护性。通过合理使用 Hooks，开发者可以更高效地构建和管理复杂的 React 应用。
 */
import React, { memo } from 'react'
import { useSelector, useDispatch, shallowEqual } from 'react-redux'
import { incrementAction, decrementAction, changeMessageAction } from './store/modules/counter'

// memo高阶组件包裹起来的组件有对应的特点: 只有props发生改变时, 才会重新渲染
const Home = memo((props) => {
  const { message } = useSelector((state) => ({
    message: state.counter.message
  }), shallowEqual)

  const dispatch = useDispatch()
  function changeMessageHandle() {
    dispatch(changeMessageAction('dispatch message'))
  }

  console.log("Home render")

  return (
    <div>
      <h2>Home: {message}</h2>
      <button onClick={e => changeMessageHandle()}>修改message</button>
    </div>
  )
})

const App = memo(() => {
  // 1.使用useSelector将redux中store的数据映射到组件内
  const { count } = useSelector(state => ({
    count: state.counter.count
  }), shallowEqual)

  // 2.使用dispatch直接派发action
  const dispatch = useDispatch()
  function addNumberHandle(num, isAdd = true) {
    if (isAdd) {
      dispatch(incrementAction(num))
    } else {
      dispatch(decrementAction(num))
    }
  }
  
  return (
    <div>
      <h2>当前计数: {count}</h2>
      <button onClick={e => addNumberHandle(1)}>+1</button>
      <button onClick={e => addNumberHandle(6)}>+6</button>
      <button onClick={e => addNumberHandle(6, false)}>-6</button>

      <Home />
    </div>
  )
})

export default App
